#include "FwdRule.h"

FwdRule::FwdRule(){

}

FwdRule::~FwdRule(){

}

FwdRule::FwdRule(const FwdRule& other )
{
    preconditions=other.preconditions;
    effect = other.effect;
}

FwdRule& FwdRule::operator=(const FwdRule& other )
{
    preconditions = other.preconditions;
    effect = other.effect;
    return *this;
}

QList<Predicate> FwdRule::getPreconditions(){
	return preconditions;
}

void FwdRule::addPrecondition(Predicate sp)
{
    preconditions.append( sp );
}

Predicate FwdRule::getEffect(){
	return effect;
}

void FwdRule::setEffect(Predicate sp){
	effect = sp;
}

std::string FwdRule::toString(){
	std::string info="[";
    QList<Predicate> cl = preconditions;
    QList<Predicate>::iterator it = cl.begin();
    while ( it != cl.end() ) {

    	info += it->toString();
        ++it;
        if ( it != cl.end() ) {

        	info += ", ";
        }
    }

    info += " -> ";
    info += effect.toString();
    info += "]";
//    if ( boundToStatement().isValid() ) {

//    	info += "bound to statement " + boundToStatement() + ")";
//    }

    return info;
}




QString FwdRule::createSparqlQuery(bool bindStatement ){
	QString query;
    if (!bindStatement) {			// 验证被绑定的statement的合法性(不是合法性，是看看有没有变量，能不能变为查询，如果语句不合法，则执行该内容，注意bindStatement是false
        for ( QList<Predicate>::iterator it = preconditions.begin();
              it != preconditions.end(); ++it ) {
            QString query_cmd = it->createSparqlGraphPattern( ).c_str();
            query+=query_cmd+ " . ";
        }
    }else{
    	//toDo
    }
    if ( !query.isEmpty() ) {
        query = "SELECT * WHERE { " + query + '}';
    }

    return query;
}

void FwdRule::bindToStatement( Statement statement )
{
    bindingStatement = statement;
}

Statement FwdRule::getBoundToStatement(){
	return bindingStatement;
}

Statement FwdRule::bindStatementPattern(Predicate pattern,NTuple bindings ){
    // below we make sure that all binding are available (in case of optimized queries the bindingStatement must not have changed)
    Statement s;
    if ( pattern.subjectPattern().isVariable() ) {
//    	std::cout << "The pattern subject is variable!" << std::endl;
    	std::vector<Binding>::iterator it_beg=bindings.bindings.begin();
    	std::vector<Binding>::iterator it_end=bindings.bindings.end();
    	std::vector<Binding>::iterator it;
    	for(it=it_beg;it!=it_end;it++){
    		if(!(it->getVariable().compare(pattern.subjectPattern().getName()))){ //找到了符合的帮定名字
//    			std::cout << "found the subject variable!" << std::endl;
    			break;
    		}
    	}
    	if(it!=it_end)
        	s.setSubject(it->getValue());
    	else
    		std::cout << "I can't find the appropriate binding!" << std::endl;
    }
    else {
        s.setSubject( pattern.subjectPattern());
    }

    if ( pattern.predicatePattern().isVariable() ) {
//    	std::cout << "The pattern predicate is variable!" << std::endl;
    	std::vector<Binding>::iterator it_beg=bindings.bindings.begin();
    	std::vector<Binding>::iterator it_end=bindings.bindings.end();
    	std::vector<Binding>::iterator it;
    	for(it=it_beg;it!=it_end;it++){
    		if(!(it->getVariable().compare(pattern.predicatePattern().getName()))) //找到了符合的帮定名字
    			break;
    	}
    	if(it!=it_end)
        	s.setPredicate(it->getValue());
    	else
    		std::cout << "I can't find the appropriate binding!" << std::endl;
    }
    else {
    	std::cout << pattern.toString() << std::endl;
        s.setPredicate( pattern.predicatePattern() );
    }

    if ( pattern.objectPattern().isVariable() ) {
//    	std::cout << "The pattern object is variable!" << std::endl;
    	std::vector<Binding>::iterator it_beg=bindings.bindings.begin();
    	std::vector<Binding>::iterator it_end=bindings.bindings.end();
    	std::vector<Binding>::iterator it;
    	for(it=it_beg;it!=it_end;it++){
    		if(!(it->getVariable().compare(pattern.objectPattern().getName()))) //找到了符合的帮定名字
    			break;
    	}
    	if(it!=it_end)
        	s.setObject(it->getValue());
    	else
    		std::cout << "I can't find the appropriate binding!" << std::endl;
    }
    else {
        s.setObject( pattern.objectPattern() );
    }

    return s;
}

Statement FwdRule::bindEffect(NTuple bindings ){
//	return bindStatementPattern( effect, mergeBindingStatement( bindings ) );
	return bindStatementPattern( effect, bindings);  //因为我们没有经过优化，所以这里的bindings就是所有的完全体
}

NTuple FwdRule::mergeBindingStatement(NTuple bindings )
{
    //
    // Here we regenerate the information (bindings) we "removed" for optimization purposes in createSparqlGraphPattern
    // This can simply be done by matching the bindingStatement which was used to optimize the query to the precondition
    // that has no binding yet. Because that is the one which was removed from the optmized query
    //

	//因为我们在这里没有经过优化，所以这一步应该不是必要的步骤
//	BindingSet bs( bindings );
	NTuple bs(bindings);
    for ( QList<Predicate>::const_iterator it = preconditions.constBegin();
          it != preconditions.constEnd(); ++it ) {
        Predicate pattern = *it;
//        if ( pattern.subjectPattern().isVariable() && bindings[pattern.subjectPattern().variableName()].isValid() ) {
//            continue;
//        }
//        if ( pattern.predicatePattern().isVariable() && bindings[pattern.predicatePattern().variableName()].isValid() ) {
//            continue;
//        }
//        if ( pattern.objectPattern().isVariable() && bindings[pattern.objectPattern().variableName()].isValid() ) {
//            continue;
//        }

        if(pattern.arguments==2){
        	if(pattern.argument1.getType()==RDFS_VARIABLE && bindings.isContain(pattern.argument1.getName())){	//argument1 是 subject
        		continue;
        	}
        	if(pattern.argument2.getType()==RDFS_VARIABLE && bindings.isContain(pattern.argument1.getName())){ //argument2 是 object
        		continue;
        	}
        }else{
        	if(pattern.argument1.getType()==RDFS_VARIABLE && bindings.isContain(pattern.argument1.getName())){	//argument1 是 subject
        		continue;
        	}
        	if(pattern.argument2.getType()==RDFS_VARIABLE && bindings.isContain(pattern.argument1.getName())){ //argument2 是 predicate
        		continue;
        	}
        	if(pattern.argument3.getType()==RDFS_VARIABLE && bindings.isContain(pattern.argument1.getName())){	//argument3 是 object
        		continue;
        	}
        }

        // update bindings
//        if ( pattern.subjectPattern().isVariable() ) {  // ?a rdfs:subClassOf ?b. ?b rdfs:subClassOf ?c ----> ?a rdfs:subClassOf ?c
//            bs.insert( pattern.subjectPattern().variableName(), d->bindingStatement.subject() );
//        }
//        if ( pattern.predicatePattern().isVariable() ) {
//            bs.insert( pattern.predicatePattern().variableName(), d->bindingStatement.predicate() );
//        }
//        if ( pattern.objectPattern().isVariable() ) {
//            bs.insert( pattern.objectPattern().variableName(), d->bindingStatement.object() );
//        }
    }

    return bs;
}

bool FwdRule::match(Statement statement){
    for ( QList<Predicate>::iterator it = preconditions.begin();
          it != preconditions.end(); ++it ) {
        if ( it->match( statement ) ) {
            return true;
        }
    }
    return false;
}



